'use strict';
// const jwt = require('jsonwebtoken');

const {
  USER_ALREADY_EXISTS,
  USER_NOT_EXISTS,
  USER_PASSWORD_ERR,
} = require('../constant');

const { userRules } = require('../rules/user');

const { hash, compare } = require('../tools');

const Controller = require('egg').Controller;

class UserController extends Controller {
  // GET /user
  async index() {
    const { ctx, app } = this;
    const { page_size = 10, page_num = 1, ...where } = ctx.request.query;

    const result = await this.ctx.service.user.list({
      page_size,
      page_num,
      where,
    });

    result.isErr
      ? app.emit('server.params.error', { ctx, error: result.error })
      : app.emit('req.success', { ctx, result });
  }

  // GET /user/:id
  async show() {
    const { id } = this.ctx.params;
    this.ctx.body = await this.ctx.service.user.find(id);
  }

  // POST /user
  async create() {
    const { ctx, app } = this;
    const { username, password } = ctx.request.body;

    const valid = ctx.validParams(userRules.create, { username, password });

    if (!valid) {
      const userExists = await ctx.model.User.findOne({
        where: { username },
      });

      if (userExists) {
        app.emit('server.params.error', {
          ctx,
          error: { msg: USER_ALREADY_EXISTS },
        });
      } else {
        const pwd = await hash(password);

        const result = await this.ctx.service.user.create({
          username,
          password: pwd,
        });

        result.isErr
          ? app.emit('server.params.error', { ctx, error: result.error })
          : app.emit('req.success', { ctx, result });
      }
    }
  }

  // POST /user/login
  async login() {
    const { ctx, app } = this;
    const { username, password } = ctx.request.body;

    const valid = ctx.validParams(userRules.create, { username, password });

    if (!valid) {
      const userExists = await ctx.model.User.findOne({
        where: { username },
      });

      if (userExists) {
        const matched = await compare(password, userExists.password);
        if (matched) {
          const { password, ...userInfo } = userExists.dataValues;

          const token = app.jwt.sign(userInfo, app.config.jwt.secret, {
            expiresIn: app.config.jwt.expiresIn,
          });

          ctx.app.emit('req.success', {
            ctx,
            result: { token, userInfo },
          });
        } else {
          ctx.app.emit('client.params.error', {
            ctx,
            error: { msg: USER_PASSWORD_ERR },
          });
        }
      } else {
        ctx.app.emit('server.params.error', {
          ctx,
          error: { msg: USER_NOT_EXISTS },
        });
      }
    }
  }

  // PUT /user/:id
  async update() {
    const { id } = this.ctx.params;
    const user = await this.ctx.service.user.update(id, this.ctx.request.body);
    this.ctx.body = user;
  }

  // DELETE /user/:id
  async destroy() {
    const { id } = this.ctx.params;
    await this.ctx.service.user.delete(id);
    this.ctx.body = { success: true };
  }
}

module.exports = UserController;
